perm filename GRAFIX.SAI[PIC,HE]1 blob
sn#423180 filedate 1979-03-07 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 entry
C00015 ENDMK
C⊗;
entry;
begin "grafix"
comment August 2, 1978 .
This module implements routines to handle graphics on the
Tektronix terminal. Every attempt is made to provide routines
that are device-independent. The following is the prescription
for producing displays.
clipinit begindisplay 'display' endisplay
endcomment;
require "define.sai" source!file;
require "gabbrv.sai" source!file;
integer rbeg, cbeg; ! Top left-hand corner of window to be
displayed;
integer rend, cend; ! Bottom right-hand corner of window;
integer rwsz, cwsz; ! Window size;
integer rowsz, colsz; ! Size of picture;
integer curr, curc; ! current position of cursor on the screen;
integer size; ! size defining the window;
boolean vectors; ! whether or not to draw st lines with
arrow heads;
real arrowlength; ! length of the arrowheads;
STRING S;
DEFINE CLIPCHECK = "FALSE";
internal simple procedure resetwindow;
! Procedure to set the screen. Assumes correct size
parameters in the variables rbeg, cbeg, rend, cend, and
size.;
vwindo(cbeg*1.0,size*1.33,-rend*1.0,size*1.0);
internal simple boolean procedure rcok(integer r, c);
! Checks whether a point is within the window.;
return(rbeg <= r <= rend and cbeg <= c <= cend);
internal simple procedure clipdsp(integer r1, c1, r2, c2);
begin "clip"
integer cd1, cd2;
real theta, rrp, ccp, rrm, ccm; ! variables for displaying
arrow heads;
integer nswap; ! No of times swapping is done;
! Produces a clipped line inside the window. This same
implementation is given in
Newmann & Sproull, Principles of Interactive Computer Graphics,
McGraw-Hill, 1973, p.124.;
simple integer procedure code(integer r, c);
return(( if r < rbeg then '01 else (if r > rend then '10 else 0)) +
(if c < cbeg then '100 else (if c > cend then '1000 else 0)));
cd1 := code(r1,c1); cd2 := code(r2,c2); nswap := 0;
IFC CLIPCHECK THENC
PRINT("CODES",CD1," ",CD2,CRLF);
s := INTTY; ENDC
while not(cd1 = cd2 = 0) do
begin
IFC CLIPCHECK THENC
IF CD1 LAND CD2 THEN
PRINT(" NOT VISIBLE",R1," ",C1," ",R2," ",C2,CRLF);
s := INTTY; ENDC
if cd1 land cd2 then return;
if cd1 = 0 then
begin
cd1 swap cd2; r1 swap r2; c1 swap c2; nswap := nswap + 1;
end;
if cd1 land '1 then
begin
c1 := c1 + (c2-c1)*(rbeg-r1)/(r2-r1); r1 := rbeg;
end else
if cd1 land '10 then
begin
c1 := c1 + (c2-c1)*(rend-r1)/(r2-r1); r1 := rend;
end else
if cd1 land '100 then
begin
r1 := r1 + (r2-r1)*(cbeg-c1)/(c2-c1); c1 := cbeg;
end else
if cd1 land '1000 then
begin
r1 := r1 + (r2-r1)*(cend-c1)/(c2-c1); c1 := cend;
end;
cd1 := code(r1,c1);
end;
IFC CLIPCHECK THENC
PRINT(" CLIPPED LINE",R1," ",C1," TO ",R2," ",C2,CRLF);
s := INTTY;
ELSEC
movea(1.0*c1,-1.0*r1); drawa(1.0*c2,-1.0*r2);
if vectors then
begin
if not even(nswap) then
begin
r1 swap r2; c1 swap c2;
end;
theta := myatan(c2-c1,r2-r1);
rrp := cosd(theta+135) * arrowlength;
ccp := sind(theta+135) * arrowlength;
rrm := - ccp; ccm := rrp;
drawa(1.0*(c2+ccp),-1.0*(r2+rrp));
movea(1.0*(c2+ccm),-1.0*(r2+rrm));
drawa(1.0*c2,-1.0*r2);
end;
ENDC
end "clip" ;
internal sIMPLE PROCEDURE ARDSTR(STRING sTR);
BEGIN
INTEGER I,CHA;
FOR I←1 sTEP 1 UNTIL LENGTH(STR) DO
BEGIN CHA←STR[I FOR 1];
IF CHA='12 THEN LINEF ELSE IF CHA='15 THEN CARTN
ELSE ANCHO(CHA);
END;
END;
internal simple procedure dcrlf;
begin
! Produces an equivalent of carriage-return and line-feed for
alphameric display.;
curr := curr + 3;
movea(1.0*curc,-1.0*curr);
end;
internal simple procedure movecursor(integer r, c);
begin
! Moves cursor on the screen to the designated point.;
curr := r; curc := c; movea(1.0*c,-1.0*r);
end;
INTERnal simple procedure legend(string pic);
begin
integer sz;
! Procedure to produce a legend on the Tektronix terminal.
The legend is produced in the upper right-hand corner of the
screen.;
sz := 100; curr := 5; curc := 76;
vwindo(0.0,1.0*sz,-1.0*sz,1.0*sz);
movecursor(curr,curc); ardstr(pic); dcrlf; dcrlf;
ardstr("top left corner: "); dcrlf;
ardstr(cvs(rbeg)&" "&cvs(cbeg)); dcrlf; dcrlf;
ardstr("window: "); dcrlf;
ardstr(cvs(rwsz)&" X "&cvs(cwsz)); dcrlf; dcrlf;
end;
internal simple procedure linelegend(string s);
begin
! Produces a single line of legend, whatever it may be.;
ardstr(s); dcrlf;
end;
simple procedure border;
begin
! Bordering the picture on the terminal screen.;
! produces border on the terminal;
movea(1.0*cbeg,-1.0*rbeg);
drawa(1.0*cbeg,-1.0*rend);
drawa(1.0*cend,-1.0*rend);
drawa(1.0*cend,-1.0*rbeg);
drawa(1.0*cbeg,-1.0*rbeg);
end;
internal simple procedure cliptest;
begin
! Procedure to test
procedure clipdsp
defined above.;
integer r1, c1, r2, c2;
iprmpt(" rbeg",rbeg); iprmpt(" rend",rend);
iprmpt(" cbeg",cbeg); iprmpt(" cend",cend);
do begin
iprmpt(" r1",r1); iprmpt(" c1",c1);
iprmpt(" r2",r2); iprmpt(" c2",c2);
clipdsp(r1,c1,r2,c2);
print(r1," ",c1," ",r2," ",c2," ",crlf);
end until false;
end;
internal simple procedure clipinit(integer r, c);
begin
! Initialising this module.;
rowsz := r; colsz := c; rbeg := 1; cbeg := 1;
size := r; if c > size then size := c;
rwsz := r; cwsz := c; rend := r; cend := c;
vectors := false;
end;
simple procedure graphicswindow;
begin
do begin
print(" specify window.",crlf);
iprmpt(" row begin",rbeg); iprmpt(" col begin",cbeg);
rwsz := rowsz - rbeg + 1; cwsz := colsz - cbeg+ 1;
iprmpt(" no of rows",rwsz); iprmpt(" no of cols",cwsz);
rend := rbeg + rwsz - 1; cend := cbeg + cwsz - 1;
end until 1 <= rbeg <= rowsz and 1 <= rend <= rowsz
and 1 <= cbeg <= colsz and 1 <= cend <= colsz;
size := rwsz; if cwsz > rwsz then size := cwsz;
arrowlength := size/128.0;
end;
simple procedure startdisplay;
begin
! Make sure you set up the size parameters all right ;
pctr(0); initt(450);
resetwindow; border;
movecursor(rbeg,rend);
end;
internal simple procedure endisplay;
begin
linelegend(date); linelegend(ttime);
movecursor(rend,cend);
endpct;
end;
internal simple procedure dashedline(integer fr,fc,tr,tc);
begin
! Given from and to coordinates, produces a dashed line.;
movea(1.0*fc,-1.0*fr); dasha(1.0*tr,-1.0*tc);
curr := tr; curc := tc;
end;
internal simple procedure begindisplay;
begin
bprmpt(" Vectors ?",vectors);
graphicswindow; startdisplay;
end;
internal simple procedure drawline(integer r, c);
begin
! Draws a line from wherever the cursor is to the point
specified. Cursoris moved also;
clipdsp(curr,curc,r,c); curr := r; curc := c;
end;
INTERnal simple procedure dispid(integer id, r, c);
begin
! Displays an integer at the given coordinates.;
if rcok(r,c) then
begin
movecursor(r,c); ardstr(cvs(id));
end;
end;
internal simple procedure clipoint(integer r,c);
begin
! displays a point, if within the window.;
if rcok(r,c) then pointa(1.0*c,-1.0*r);
end;
internal simple procedure getwindow(reference integer r1,c1,r2,c2);
begin
! Returns the top left-hand and bottom right-hand corners of the
current window;
r1 := rbeg; c1 := cbeg; r2 := rend; c2 := cend;
end;
internal simple procedure drawvectors;
vectors := true;
internal simple procedure novectors;
vectors := false;
end "grafix";